﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using SharpSvn;
using SharpSvn.UI;
using System.Net;
using System.IO;

namespace SvnLauncher
{
    public partial class Form1 : Form
    {
        private bool serverstatus = false;
        private string hostname = "";
        private string connectinfo = "";
        private string location = @""+Application.StartupPath; // change
        private bool isOwnServer = false;
     
        public Form1()
        {
            InitializeComponent();
        }

     
        private void UpdateStatus()
        {
           SvnCheckOutArgs args = new SvnCheckOutArgs();
            
            SvnUpdateResult result;
            
            using (SvnClient client = new SvnClient())
            {
                try
                {
                   
                    //SvnUriTarget is a wrapper class for SVN repository URIs
                    SvnUriTarget target = new SvnUriTarget("https://pl3.projectlocker.com/mclcontrib/MCLauncher/svn/stats");
                    client.Authentication.DefaultCredentials = new NetworkCredential("philipp.rettig@freenet.de", "sobase43");
                    //this is the where 'svn checkout' actually happens.
                    if (client.CheckOut(target, this.location+"//stats", args, out result))
                    {
                        StreamReader sr = new StreamReader(this.location + "//stats//status.txt");
                        String txt = sr.ReadLine();
                        String[] parts = txt.Split(';');
                        this.label4.Text = parts[0];
                        this.hostname = parts[1];
                        this.connectinfo = parts[2];
                        if (this.label4.Text == "Online")
                        {
                            this.label4.ForeColor = Color.Green;
                            this.serverstatus = true;
                            this.textBox1.Text = this.hostname;
                            this.textBox2.Text = this.connectinfo;
                            this.button3.Enabled = false;
                            
                        }
                        else
                        {
                            this.label4.ForeColor = Color.Red;
                            this.serverstatus = false;
                            this.textBox1.Text = "";
                            this.textBox2.Text = "";
                        }
                        sr.Close();
                   

                        StreamReader srdr = new StreamReader("ActiveRev.txt");
                        long activerev = long.Parse(srdr.ReadLine());
                        SvnInfoEventArgs info;

                        client.GetInfo(target, out info);
                        srdr.Close();

                        if (activerev == info.Revision)
                        {
                            this.label6.Text = "YES";
                            this.label6.ForeColor = Color.Green;
                            if (!this.serverstatus)
                            {
                                this.checkBox1.Enabled = true;
                                this.textBox1.Enabled = true;
                                this.textBox2.Enabled = true;
                                this.button3.Enabled = false;
                            }
                        }
                        else
                        {
                            this.label6.Text = "NO";
                            if (!this.serverstatus)
                            {
                                this.button3.Enabled = true;
                            }
                            this.label6.ForeColor = Color.Red;
                        }
                     
                    }
                }
                catch (SvnException se)
                {
                    MessageBox.Show(se.Message,
                    "svn checkout error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                }
                catch (UriFormatException ufe)
                {
                    MessageBox.Show(ufe.Message,
                    "svn checkout error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                }
            }                  
                    
        }

        private void WriteStatus()
        {
            String servstat ="Online";
            if (!this.serverstatus) servstat = "Offline";
            StreamWriter sw = new StreamWriter(this.location + "//stats//status.txt");
            sw.Write(servstat + ";" + this.hostname + ";" + this.connectinfo + ";");
            sw.Flush();
            sw.Close();
        }

        private void SVNCheckout()
        {
            this.label6.Text = "checking...";
            this.label6.ForeColor = Color.Black;
            SvnCheckOutArgs args = new SvnCheckOutArgs();
            
            SvnUpdateResult result;
            
            using (SvnClient client = new SvnClient())
            {
                try
                {
                    
                    //SvnUriTarget is a wrapper class for SVN repository URIs
                    SvnUriTarget target = new SvnUriTarget("https://pl3.projectlocker.com/mclcontrib/MCLauncher/svn/world");
                    client.Authentication.DefaultCredentials = new NetworkCredential("philipp.rettig@freenet.de", "sobase43");
                    //this is the where 'svn checkout' actually happens.
                    if (client.CheckOut(target, this.location+"//world", args, out result))
                    {
                        MessageBox.Show("Successfully updated data at Revision " + result.Revision + ".", "Success");
                        TextWriter sw = new StreamWriter("ActiveRev.txt");
                        sw.Write(result.Revision);
                        sw.Flush();
                        sw.Close();
                    }
                 
                }
                catch (SvnException se)
                {
                    MessageBox.Show(se.Message,
                    "svn checkout error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                }
                catch (UriFormatException ufe)
                {
                    MessageBox.Show(ufe.Message,
                    "svn checkout error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                }
            }
            
        }
    
        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.UpdateStatus();
            if (this.label4.Text == "Offline" && this.label6.Text == "YES")
            {
                this.textBox1.Enabled = true;
                this.textBox2.Enabled = true;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Process p = new Process();
            p.StartInfo.FileName = "smc.exe";
            p.StartInfo.UseShellExecute = false;
            p.Start();
            this.button2.Text = "Started...";
            this.button2.Enabled = false;
            p.WaitForExit();
            this.button2.Text = "Start Minecraft";
            this.button2.Enabled = true;
        }

        private void SVNCommit()
        {
            SvnCommitArgs args = new SvnCommitArgs();
            args.LogMessage = "User '"+this.hostname+" used MCLauncher. HTC: "+this.connectinfo;
                        
            SvnCommitResult result;

            using (SvnClient client = new SvnClient())
            {
                try
                {
                    client.Authentication.Clear();
                    client.Authentication.DefaultCredentials = new NetworkCredential("philipp.rettig@freenet.de", "sobase43");

                    //Bind allows the client to prompt the user for authentication info.
                    SvnUI.Bind(client, this.label1);

                    //This method is the equivalent of 'svn commit'
                    client.Commit(this.location + "//stats", args, out result);
                    client.Commit(this.location + "//world", args, out result);
                    if (result != null)
                        MessageBox.Show("Successfully commited revision " + result.Revision);
                }
                catch (SvnException se)
                {
                    MessageBox.Show(se.Message + "Error: " + se.SvnErrorCode + Environment.NewLine,
                    "svn commit error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                }
            }
        }

        private void label5_Click(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.SVNCheckout();
            this.UpdateStatus();
            
            if (this.label4.Text == "Offline" && this.label6.Text == "YES")
            {
                this.textBox1.Enabled = true;
                this.textBox2.Enabled = true;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (this.serverstatus == true)
            {
                MessageBox.Show("A server is already running!", "Error");
                return;
            }

            if (this.label6.Text == "NO" || this.label6.Text == "checking...")
            {
                MessageBox.Show("Update data first!", "Error");
                return;
            }

            if (this.textBox1.Text == "" || this.textBox2.Text == "")
            {
                MessageBox.Show("'Hostname' and 'How to connect' required!", "Error");
                return;
            }

            if (this.textBox2.Text.Contains(';') || this.textBox1.Text.Contains(';'))  
            {
                MessageBox.Show("'Hostname' and 'How to connect' are not allowed to contain ';'.", "Error");
                return;
            }

            if (this.checkBox1.Checked && this.textBox3.Text == "")
            {
                MessageBox.Show("IP is needed when using Hamachi!", "Error");
                return;
            }
            this.WriteConfig(this.checkBox1.Checked);
            this.connectinfo = textBox2.Text;
            this.hostname = textBox1.Text;

            Process p = new Process();
            p.StartInfo.FileName = "java";
            p.StartInfo.Arguments = "-Xmx1024M -Xms1024M -jar mcs.jar nogui";
            p.Start();

            this.isOwnServer = true;
            this.serverstatus = true;
            this.WriteStatus();
            this.label4.Text = "Online";
            this.label4.ForeColor = Color.Green;
            this.textBox1.Enabled = false;
            this.textBox2.Enabled = false;
            p.EnableRaisingEvents = true;
            p.Exited += this.OnServerDown;
            
            this.SVNCommit();
        }

        private void OnServerDown(Object sender, EventArgs e)
        {
            if (InvokeRequired)
                Invoke(new EventHandler(OnServerDown),
                            new object[] { sender, e });
            else
            {
                this.serverstatus = false;
                this.isOwnServer = false;
                this.hostname = "-";
                this.connectinfo = " ";
                this.WriteStatus();
                label4.Text = "Offline";
                this.label4.ForeColor = Color.Red;
                if (this.label4.Text == "Offline" && this.label6.Text == "YES")
                {
                    this.textBox1.Enabled = true;
                    this.textBox2.Enabled = true;
                }
                this.SVNCommit();
                StreamReader sr = new StreamReader("Activerev.txt");
                long rev = long.Parse(sr.ReadLine());
                sr.Close();
                rev += 4;
                TextWriter sw = new StreamWriter("ActiveRev.txt");
                sw.Write(""+rev);
                sw.Flush();
                sw.Close();
            }
            
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (this.isOwnServer)
            {
                MessageBox.Show("Server is still running!", "Error");
                return;
            }
            Application.Exit();
        }

        private void label8_Click(object sender, EventArgs e)
        {

        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            this.textBox3.Enabled = !this.textBox3.Enabled;
        }

        private void WriteConfig(bool hamachi)
        {
            TextWriter sw = new StreamWriter("server.properties");
            sw.WriteLine("#Minecraft server properties"); 
            sw.WriteLine("#Auto Generated by Minecraft Launcher");
            sw.WriteLine("level-name=world");
            sw.WriteLine("allow-nether=true");
            sw.WriteLine("view-distance=10");
            sw.WriteLine("spawn-monsters=false");
            if (this.checkBox1.Checked)
                sw.WriteLine("online-mode=false");
            else
                sw.WriteLine("online-mode=true");
            sw.WriteLine("spawn-animals=true");
            sw.WriteLine("max-players=20");
            sw.WriteLine("server-ip="+this.textBox3.Text);
            sw.WriteLine("pvp=true");
            sw.WriteLine("level-seed=");
            sw.WriteLine("server-port=25565");
            sw.WriteLine("allow-flight=true");
            sw.WriteLine("white-list=false");
            sw.Flush();
            sw.Close();

        }



       
    }
}
